From b9cd4450f8a869d848db2a4d73608100eea02492 Mon Sep 17 00:00:00 2001 From: "smh22@firebug.cl.cam.ac.uk" Date: Thu, 28 Apr 2005 13:52:41 +0000 Subject: [PATCH] bitkeeper revision 1.1389.1.1 (4270eaa9i26XkdEPCi0_DHgtMgxvAw) fix 2.4 build --- .rootkeys | 1 + .../arch/xen/kernel/pci-dma.c | 137 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 linux-2.4.29-xen-sparse/arch/xen/kernel/pci-dma.c diff --git a/.rootkeys b/.rootkeys index 08ca71bd84..701263e1f8 100644 --- a/.rootkeys +++ b/.rootkeys @@ -152,6 +152,7 @@ 4241709bNBs1q4Ss32YW0CyFVOGhEg linux-2.4.29-xen-sparse/arch/xen/kernel/ioport.c 3e5a4e653U6cELGv528IxOLHvCq8iA linux-2.4.29-xen-sparse/arch/xen/kernel/irq.c 3e5a4e65muT6SU3ck47IP87Q7Ti5hA linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c +4270e964iKFC24KiVm6jC5Eo7MxV6w linux-2.4.29-xen-sparse/arch/xen/kernel/pci-dma.c 4051db95N9N99FjsRwi49YKUNHWI8A linux-2.4.29-xen-sparse/arch/xen/kernel/pci-pc.c 3e5a4e65IGt3WwQDNiL4h-gYWgNTWQ linux-2.4.29-xen-sparse/arch/xen/kernel/process.c 3e5a4e66tR-qJMLj3MppcKqmvuI2XQ linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c diff --git a/linux-2.4.29-xen-sparse/arch/xen/kernel/pci-dma.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/pci-dma.c new file mode 100644 index 0000000000..c984bc6173 --- /dev/null +++ b/linux-2.4.29-xen-sparse/arch/xen/kernel/pci-dma.c @@ -0,0 +1,137 @@ +/* + * Dynamic DMA mapping support. + * + * On i386 there is no hardware dynamic DMA address translation, + * so consistent alloc/free are merely page allocation/freeing. + * The rest of the dynamic DMA mapping interface is implemented + * in asm/pci.h. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define pte_offset_kernel pte_offset + +struct dma_coherent_mem { + void *virt_base; + u32 device_base; + int size; + int flags; + unsigned long *bitmap; +}; + +static void +xen_contig_memory(unsigned long vstart, unsigned int order) +{ + /* + * Ensure multi-page extents are contiguous in machine memory. + * This code could be cleaned up some, and the number of + * hypercalls reduced. + */ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + unsigned long pfn, i, flags; + + scrub_pages(vstart, 1 << order); + + balloon_lock(flags); + + /* 1. Zap current PTEs, giving away the underlying pages. */ + for (i = 0; i < (1<pte_low >> PAGE_SHIFT; + HYPERVISOR_update_va_mapping( + vstart + (i*PAGE_SIZE), __pte_ma(0), 0); + phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = + INVALID_P2M_ENTRY; + if (HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, + &pfn, 1, 0) != 1) BUG(); + } + /* 2. Get a new contiguous memory extent. */ + if (HYPERVISOR_dom_mem_op(MEMOP_increase_reservation, + &pfn, 1, order) != 1) BUG(); + /* 3. Map the new extent in place of old pages. */ + for (i = 0; i < (1<>PAGE_SHIFT)+i); + phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = + pfn+i; + } + /* Flush updates through and flush the TLB. */ + flush_tlb_all(); + + balloon_unlock(flags); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle) +#else +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int gfp) +#endif +{ + void *ret; + unsigned int order = get_order(size); + unsigned long vstart; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + int gfp = GFP_ATOMIC; + + if (hwdev == NULL || ((u32)hwdev->dma_mask < 0xffffffff)) + gfp |= GFP_DMA; +#else + struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; + + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); + + if (mem) { + int page = bitmap_find_free_region(mem->bitmap, mem->size, + order); + if (page >= 0) { + *dma_handle = mem->device_base + (page << PAGE_SHIFT); + ret = mem->virt_base + (page << PAGE_SHIFT); + memset(ret, 0, size); + return ret; + } + if (mem->flags & DMA_MEMORY_EXCLUSIVE) + return NULL; + } + + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) + gfp |= GFP_DMA; +#endif + + vstart = __get_free_pages(gfp, order); + ret = (void *)vstart; + if (ret == NULL) + return ret; + + xen_contig_memory(vstart, order); + + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + + return ret; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} -- 2.30.2